package logic

import (
	"context"
	"fmt"
	"gitee.com/dn-jinmin/chatcms/internal/logic/ai/base"
	"strings"

	"gitee.com/dn-jinmin/chatcms/internal/domain"
	"gitee.com/dn-jinmin/chatcms/internal/logic/ai"
	"gitee.com/dn-jinmin/chatcms/internal/svc"
	"gitee.com/dn-jinmin/chatcms/pkg/curl"
	"gitee.com/dn-jinmin/langchaingo"
	"github.com/tmc/langchaingo/chains"
)

type AI interface {
	ModelList(ctx context.Context) (resp *domain.ModelListResp, err error)
	Chat(ctx context.Context, req *domain.AIChatReq) (resp *domain.AIChatResp, err error)
}

type aI struct {
	svcCtx *svc.ServiceContext
	ai     *ai.Ai
}

func NewAI(svcCtx *svc.ServiceContext) AI {
	return &aI{
		svcCtx: svcCtx,
		ai:     ai.NewAi(svcCtx),
	}
}

// OllamaTagsResponse represents the response structure from Ollama API
type OllamaTagsResponse struct {
	Models []struct {
		Name string `json:"name"`
	} `json:"models"`
}

func (l *aI) ModelList(ctx context.Context) (resp *domain.ModelListResp, err error) {
	// 构造Ollama API URL
	ollamaURL := fmt.Sprintf("%s/api/tags", l.svcCtx.Config.Ollamas.URL)

	// 发送请求并获取响应
	var ollamaResp OllamaTagsResponse
	if err := curl.Get(ollamaURL, nil, &ollamaResp); err != nil {
		return nil, fmt.Errorf("调用Ollama API失败: %w", err)
	}

	// 转换响应格式
	models := make([]*domain.Model, 0, len(ollamaResp.Models))
	for _, model := range ollamaResp.Models {
		models = append(models, &domain.Model{
			Name:  model.Name,
			Value: model.Name,
		})
	}

	return &domain.ModelListResp{
		List: models,
	}, nil
}

func (l *aI) Chat(ctx context.Context, req *domain.AIChatReq) (resp *domain.AIChatResp, err error) {
	input := map[string]any{
		langchaingo.Input: req.Message,
	}
	ctx = context.WithValue(ctx, base.InputModel, req.Model)
	ctx = context.WithValue(ctx, base.InputThink, req.Reasoning)
	out, err := chains.Call(ctx, l.ai, input)
	if err != nil {
		return nil, fmt.Errorf("调用Ollama API失败: %w", err)
	}

	text := out[langchaingo.OutPutKey].(string)
	if strings.Contains(text, "</think>") {
		think := strings.Split(text, "</think>")[0]
		text = strings.Split(text, "</think>")[1]

		text = fmt.Sprintf("思考: %s<br/><br/>话术: %s", think, text)
	}

	resp = &domain.AIChatResp{
		Content: text,
	}
	return resp, nil

}
